package com.qf.controller;


import com.hazelcast.util.StringUtil;
import com.qf.captcha.CaptchaCodeManager;
import com.qf.pojo.DtsAdmin;
import com.qf.service.AdminService;
import com.qf.service.PermsService;
import com.qf.service.RoleService;
import com.qf.util.*;
import com.qf.util.Base64;
import com.qf.util.UUID;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@CrossOrigin
@RestController
@RequestMapping("/admin/auth")
public class AdminAuthController {

    @Autowired
    private AdminService adminService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private PermsService permsService;
    @Autowired
    private ApplicationContext applicationContext;


    @GetMapping("/captchaImage")
    public Object captchaImage() throws IOException {

        String uuid = UUID.randomUUID().toString();

        String code = VerifyCodeUtils.generateVerifyCode(4);

        CaptchaCodeManager.addToCache(uuid,code,null);

        ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();

        VerifyCodeUtils.outputImage(100,36,byteOutputStream,code);

        byte[] bytes = byteOutputStream.toByteArray();

        Map map=new HashMap();
        map.put("uuid",uuid);
        map.put("img", Base64.encode(bytes));

        return ResponseUtil.ok(map);


    }


    @PostMapping("/login")
    public Object login(@RequestBody String adminJson){

        String username = JacksonUtil.parseString(adminJson, "username");
        String password = JacksonUtil.parseString(adminJson, "password");
        String code = JacksonUtil.parseString(adminJson, "code");
        String uuid = JacksonUtil.parseString(adminJson, "uuid");

        if (StringUtil.isNullOrEmptyAfterTrim(code)){
            return ResponseUtil.fail(-1,"验证码不能为空");
        }
        String cachedCaptcha = CaptchaCodeManager.getCachedCaptcha(uuid);
        System.out.println(cachedCaptcha);
        System.out.println(code);
        if (StringUtil.isNullOrEmptyAfterTrim(cachedCaptcha)){
            return ResponseUtil.fail(-1,"验证码已经过期");
        }
        if (!code.equalsIgnoreCase(cachedCaptcha)){
            return ResponseUtil.fail(-1,"验证码不正确");
        }

        if (StringUtil.isNullOrEmptyAfterTrim(username)){
            return ResponseUtil.fail(-1,"用户名不能为空");
        }
        if (StringUtil.isNullOrEmptyAfterTrim(password)){
            return ResponseUtil.fail(-1,"密码不能为空");
        }

        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token=new UsernamePasswordToken(username,password);

        try {
            subject.login(token);
        } catch (Exception e) {
            return ResponseUtil.fail(-1,e.getMessage());
        }


        return ResponseUtil.ok(subject.getSession().getId());
    }

    //必须登录才能访问
    @RequiresUser
    @GetMapping("/info")
    public Object info(HttpServletRequest request){

        Subject subject = SecurityUtils.getSubject();
        DtsAdmin principal = (DtsAdmin) subject.getPrincipal();

        Set<String> roles = roleService.findRolesByRoleIds(principal.getRoleIds());
        Set<String> perms = permsService.findPermsByRoleIds(principal.getRoleIds());

        Map map=new HashMap();
        map.put("roles",roles);
        map.put("name",principal.getUsername());
        map.put("perms",toApi(perms));
        map.put("avatar",principal.getAvatar());

        return ResponseUtil.ok(map);


    }

    public List<String> toApi(Set<String> perms){
        //set中只要有* 就不用判断
        if (CollectionUtils.isEmpty(perms)) {
            return new ArrayList<>();
        }
        if (perms.contains("*")){
            return Arrays.asList("*");
        }

        String p="com.qf.controller";
        List<Permission> permissions=PermissionUtil.listPermission(applicationContext,p);

        List<String> collect = permissions.stream().filter((permission) -> {
            if (perms.contains(permission.getRequiresPermissions().value()[0])) {
                return true;
            } else {
                return false;
            }
        }).map(Permission::getApi).collect(Collectors.toList());

        return collect;
    }




}
